# Copyright (C) 2001, 2003-2004, 2006, 2008-2010 The Written Word, Inc.
# Copyright (C) 2000-2001 The Written Word, LLC
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# $Id: __init__.py 748 2010-11-02 11:25:38Z gary $

import sys

import sbdb
import prog.archive

from misclib import urljoin
from version import Version

from baseclass.depotbase import *

# version number and revision class
class Depot (DepotBase):
  def __init__ (self, dep):
    # This is better, but doesn't work for classic classes:
    #    super (Depot, self).__init__ (dep)
    # So, we're forced to hardcode the superclass for now:
    DepotBase.__init__ (self, dep)

    self.sbdbs = []			# list of sb-db.xml entries

  def get_sbdb_entry (self, prog_name):
    for sbdb in self.sbdbs:
      if sbdb.prog_name + '-' + sbdb.prog_ver == prog_name:
        return sbdb
    return None

  def prog_exists (self, prog_name):
    return self._db_exists (prog_name, '.sb')

  # path to XML .sb file
  def sbdb_path (self, filename):
    return urljoin (self.pkg_url, filename)


# list of repositories
class Depots (DepotsBase):
  XML_FILE = 'sb-db.xml'
  DB_SUFFIX = '.sb'

  def __init__ (self, add_package = None, assign_depot_vars = None,
                local_depot = '', modules = [], msg_callback = None,
                package_list = [], package_names = [], systype_path = '',
                tmpbasedir = '', var = {}):
    super (Depots, self).__init__ (add_package, assign_depot_vars,
                                   local_depot, msg_callback, package_names,
                                   tmpbasedir, var)

    self.modules = modules
    self.package_list = package_list
    self.systype_path = systype_path

  def add_packages (self, package, archive):
    self.add_package (package.prog_name + '-' + package.prog_ver, archive)

  def archive_init (self, path):
    return prog.archive.init (path)

  def depot_init (self, dep):
    pass

  def read_db_xml (self, archive, dep, basename):
    return sbdb.read_sbdb_xml (archive, dep.sbdbs, basename,
                               self.var['dist'], self.modules,
                               dep.dtd_dirs, self.systype_path)

  def sub_depot_filter (self, sub_depot, search_package_names):
    if sub_depot.category:
      # only interested in directories with source
      if sub_depot.category != 'src':
        return True
      if not sub_depot.auto_include:
        return True

    # if package name specified in depot add to list of
    # depots only if package name in list of packages
    # we're building
    skip = False
    if sub_depot.package:
      for package in self.package_list:
        if sub_depot.package == package.name and \
              package.name in search_package_names:
          skip = False
          break
        else:
          skip = True

    return skip

  def xml_file_filter (self, valid_depots, dep, found_depot_db_xml):
    # depot has suffixed file. Either:
    #   the package name + self.DB_SUFFIX
    #   or just self.XML_FILE
    db_filename = ''
    if dep.exists (self.XML_FILE):
      db_filename = self.XML_FILE
    else:
      for package in dep.packages:
        if dep.exists (package + self.DB_SUFFIX):
          db_filename = package + self.DB_SUFFIX
          break
      else:
        if found_depot_db_xml:
          valid_depots.append (dep)
        return True

    valid_depots.append (dep)

    self.msg_callback ('begin', 'reading ' +
                       urljoin (dep.pkg_url, db_filename), 2, VERBOSE_DEPOT)

    dep.fetch (db_filename)		# copy to local depot

    try:
      self.read_db_xml (dep, dep, db_filename)
      self.msg_callback ('end', 'done', 2, VERBOSE_DEPOT)

    except XMLError, msg:
      # Finish the callback output, and reraise the exception
      self.msg_callback ('end', 'failed', 2, VERBOSE_DEPOT)
      raise XMLError (str (msg))

    return False

def find (depots, pkg_name, module):
  latest_version = Version (0)
  latest_revision = 0
  latest_depot = None

  for dep in depots:
    for sbdb in dep.sbdbs:
      if sbdb.prog_name + '-' + sbdb.prog_ver == pkg_name:
        if module == 'all' or sbdb.modules.has_key (module):
          return dep
      elif sbdb.prog_name == pkg_name:
        prog_ver = Version (sbdb.prog_ver)

        if prog_ver > latest_version:
          latest_version = prog_ver
          latest_revision = int (sbdb.prog_rev)
          latest_depot = dep
          continue

        if prog_ver == latest_version and \
        int (sbdb.prog_rev) > latest_revision:
          latest_version = prog_ver
          latest_revision = int (sbdb.prog_rev)
          latest_depot = dep

  if latest_depot:
    return latest_depot

  raise DepotFileNotFoundError
